
"""Serves as the driver for events in the simulation"""

_simulation = None
_singleton = "DO NOT USE THIS VARIABLE OUTSIDE THIS MODULE"


def get_simulation():
    global _simulation, _singleton
    if not _simulation:
        _simulation = Simulation(_singleton)
    return _simulation

class Simulation:
    """Singleton class that unifies all aspects of the simulation"""
    
    def __init__(self, code = None):
        if code != _singleton:
            raise Exception("instantiating singleton class not permitted by " +
                            "outside 'get_simulation'")
            
        self._world = None
        self._turn_listeners = set()
        
    
    def get_world(self):
        """Get the world for this simulation"""
        if(self._world == None):
            raise Exception("World requested from simulation before the world +"
                            "has been initialized")
        return self._world
        
        
    def set_world(self, w):
        """
        Set the world for this simulation
        w - The world that the simualtion will use
        """
        self._world = w
        
    def add_turn_listener(self, l):
        """
        Adds a litener to turn endings in this simulation
        l - The listener of turn endings
        """
        if 'do_turn' not in l.__class__.__dict__:
            raise Exception("Added non turn listener to simulation, turn " +
                            "listener must def 'do_turn'")
            
        self._turn_listeners.add(l)
        
    def notify_turn_listeners(self):
        """
        Notifies all listeners of turns to do their turns
        """
        for l in self._turn_listeners:
            l.do_turn()
        
    def clear_listeners(self):
        """
        Removes all listeners.  Used frequently in testing
        """
        
        self._turn_listeners = set()
            
            
    
        
        